--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
tests/frontend/InterfacesPage.test.js 014e463527af2d3aa5ea4fc10f98d2e705093fbb (014e4635) Text, 3.86 KB
Tff7b72import Tb4b4b4{ Te6edf3mount Tb4b4b4} Tff7b72from Ta5d6ff"@vue/test-utils"Tb4b4b4;
Tff7b72import Tb4b4b4{ Te6edf3describeTb4b4b4, Te6edf3itTb4b4b4, Te6edf3expectTb4b4b4, Te6edf3viTb4b4b4, Te6edf3beforeEach Tb4b4b4} Tff7b72from Ta5d6ff"vitest"Tb4b4b4;
Tff7b72import Te6edf3InterfacesPage Tff7b72from Ta5d6ff"../../meshchatx/src/frontend/components/interfaces/InterfacesPage.vue"Tb4b4b4;
Tff7b72import Te6edf3GlobalState Tff7b72from Ta5d6ff"../../meshchatx/src/frontend/js/GlobalState"Tb4b4b4;
T8b949e// Mock global objects
Tff7b72const Te6edf3mockAxios Tff7b72= Tb4b4b4{
Te6edf3getTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3postTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4}Tb4b4b4;
Tffa657windowTb4b4b4.Te6edf3axios Tff7b72= Te6edf3mockAxiosTb4b4b4;
Tff7b72const Te6edf3mockToast Tff7b72= Tb4b4b4{
Te6edf3successTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3errorTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4}Tb4b4b4;
T8b949e// We need to handle how ToastUtils is imported in the component
T8b949e// If it's a global or imported, we might need a different approach.
T8b949e// Let's assume it's available via window or we can mock the import if using vitest aliases.
Te6edf3viTb4b4b4.Te6edf3mockTb4b4b4(Ta5d6ff"../../js/ToastUtils"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4(Tb4b4b4{
Tff7b72defaultTff7b72: Tb4b4b4{
Te6edf3successTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3errorTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Mock router/route
Tff7b72const Te6edf3mockRoute Tff7b72= Tb4b4b4{
Te6edf3queryTff7b72: Tb4b4b4{Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4;
Tff7b72const Te6edf3mockRouter Tff7b72= Tb4b4b4{
Te6edf3pushTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4}Tb4b4b4;
Te6edf3describeTb4b4b4(Ta5d6ff"InterfacesPage.vue"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3beforeEachTb4b4b4(Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3viTb4b4b4.Te6edf3clearAllMocksTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3mockAxiosTb4b4b4.Te6edf3getTb4b4b4.Te6edf3mockResolvedValueTb4b4b4(Tb4b4b4{ Te6edf3dataTff7b72: Tb4b4b4{ Te6edf3interfacesTff7b72: Tb4b4b4[Tb4b4b4]Tb4b4b4, Te6edf3app_infoTff7b72: Tb4b4b4{ Te6edf3is_reticulum_runningTff7b72: Tff7b72true Tb4b4b4} Tb4b4b4} Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3GlobalStateTb4b4b4.Te6edf3hasPendingInterfaceChanges Tff7b72= Tff7b72falseTb4b4b4;
Te6edf3GlobalStateTb4b4b4.Te6edf3modifiedInterfaceNamesTb4b4b4.Te6edf3clearTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3itTb4b4b4(Ta5d6ff"loads interfaces on mount"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3mockAxiosTb4b4b4.Te6edf3getTb4b4b4.Te6edf3mockImplementationTb4b4b4(Tb4b4b4(Te6edf3urlTb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3urlTb4b4b4.Te6edf3includesTb4b4b4(Ta5d6ff"interfaces"Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Tffa657PromiseTb4b4b4.Te6edf3resolveTb4b4b4(Tb4b4b4{ Te6edf3dataTff7b72: Tb4b4b4{ Te6edf3interfacesTff7b72: Tb4b4b4[Tb4b4b4{ Te6edf3nameTff7b72: Ta5d6ff"Test Iface"Tb4b4b4, Te6edf3typeTff7b72: Ta5d6ff"TCP" Tb4b4b4}Tb4b4b4] Tb4b4b4} Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3urlTb4b4b4.Te6edf3includesTb4b4b4(Ta5d6ff"app/info"Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Tffa657PromiseTb4b4b4.Te6edf3resolveTb4b4b4(Tb4b4b4{ Te6edf3dataTff7b72: Tb4b4b4{ Te6edf3app_infoTff7b72: Tb4b4b4{ Te6edf3is_reticulum_runningTff7b72: Tff7b72true Tb4b4b4} Tb4b4b4} Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Tffa657PromiseTb4b4b4.Te6edf3rejectTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3wrapper Tff7b72= Te6edf3mountTb4b4b4(Te6edf3InterfacesPageTb4b4b4, Tb4b4b4{
Tffa657globalTff7b72: Tb4b4b4{
Te6edf3mocksTff7b72: Tb4b4b4{
Te6edf3$routeTff7b72: Te6edf3mockRouteTb4b4b4,
Te6edf3$routerTff7b72: Te6edf3mockRouterTb4b4b4,
Te6edf3$tTff7b72: Tb4b4b4(Te6edf3msgTb4b4b4) Tb4b4b4=> Te6edf3msgTb4b4b4,
Tb4b4b4}Tb4b4b4,
Te6edf3stubsTff7b72: Tb4b4b4[Ta5d6ff"RouterLink"Tb4b4b4, Ta5d6ff"MaterialDesignIcon"Tb4b4b4, Ta5d6ff"IconButton"Tb4b4b4, Ta5d6ff"Interface"Tb4b4b4, Ta5d6ff"ImportInterfacesModal"Tb4b4b4]Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3$nextTickTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3$nextTickTb4b4b4(Tb4b4b4)Tb4b4b4; T8b949e// wait for multiple awaits
Te6edf3expectTb4b4b4(Te6edf3mockAxiosTb4b4b4.Te6edf3getTb4b4b4)Tb4b4b4.Te6edf3toHaveBeenCalledWithTb4b4b4(Ta5d6ff"/api/v1/reticulum/interfaces"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3interfacesTb4b4b4.Te6edf3lengthTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(T79c0ff1Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3itTb4b4b4(Ta5d6ff"tracks changes when an interface is enabled"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3wrapper Tff7b72= Te6edf3mountTb4b4b4(Te6edf3InterfacesPageTb4b4b4, Tb4b4b4{
Tffa657globalTff7b72: Tb4b4b4{
Te6edf3mocksTff7b72: Tb4b4b4{
Te6edf3$routeTff7b72: Te6edf3mockRouteTb4b4b4,
Te6edf3$routerTff7b72: Te6edf3mockRouterTb4b4b4,
Te6edf3$tTff7b72: Tb4b4b4(Te6edf3msgTb4b4b4) Tb4b4b4=> Te6edf3msgTb4b4b4,
Tb4b4b4}Tb4b4b4,
Te6edf3stubsTff7b72: Tb4b4b4[Ta5d6ff"RouterLink"Tb4b4b4, Ta5d6ff"MaterialDesignIcon"Tb4b4b4, Ta5d6ff"IconButton"Tb4b4b4, Ta5d6ff"Interface"Tb4b4b4, Ta5d6ff"ImportInterfacesModal"Tb4b4b4]Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3enableInterfaceTb4b4b4(Ta5d6ff"test-iface"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3hasPendingInterfaceChangesTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3modifiedInterfaceNamesTb4b4b4.Te6edf3hasTb4b4b4(Ta5d6ff"test-iface"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3itTb4b4b4(Ta5d6ff"clears pending changes after RNS reload"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3mockAxiosTb4b4b4.Te6edf3postTb4b4b4.Te6edf3mockResolvedValueTb4b4b4(Tb4b4b4{ Te6edf3dataTff7b72: Tb4b4b4{ Te6edf3messageTff7b72: Ta5d6ff"Reloaded" Tb4b4b4} Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3wrapper Tff7b72= Te6edf3mountTb4b4b4(Te6edf3InterfacesPageTb4b4b4, Tb4b4b4{
Tffa657globalTff7b72: Tb4b4b4{
Te6edf3mocksTff7b72: Tb4b4b4{
Te6edf3$routeTff7b72: Te6edf3mockRouteTb4b4b4,
Te6edf3$routerTff7b72: Te6edf3mockRouterTb4b4b4,
Te6edf3$tTff7b72: Tb4b4b4(Te6edf3msgTb4b4b4) Tb4b4b4=> Te6edf3msgTb4b4b4,
Tb4b4b4}Tb4b4b4,
Te6edf3stubsTff7b72: Tb4b4b4[Ta5d6ff"RouterLink"Tb4b4b4, Ta5d6ff"MaterialDesignIcon"Tb4b4b4, Ta5d6ff"IconButton"Tb4b4b4, Ta5d6ff"Interface"Tb4b4b4, Ta5d6ff"ImportInterfacesModal"Tb4b4b4]Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3GlobalStateTb4b4b4.Te6edf3hasPendingInterfaceChanges Tff7b72= Tff7b72trueTb4b4b4;
Te6edf3GlobalStateTb4b4b4.Te6edf3modifiedInterfaceNamesTb4b4b4.Te6edf3addTb4b4b4(Ta5d6ff"test-iface"Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3reloadRnsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3hasPendingInterfaceChangesTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3modifiedInterfaceNamesTb4b4b4.Te6edf3sizeTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3mockAxiosTb4b4b4.Te6edf3postTb4b4b4)Tb4b4b4.Te6edf3toHaveBeenCalledWithTb4b4b4(Ta5d6ff"/api/v1/reticulum/reload"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────